/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ms.bus.util;

import com.sun.codemodel.JCodeModel;
import com.sun.tools.xjc.api.ErrorListener;
import com.sun.tools.xjc.api.S2JJAXBModel;
import com.sun.tools.xjc.api.SchemaCompiler;
import com.sun.tools.xjc.api.XJC;
import java.io.File;
import java.io.IOException;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import ms.bus.xml.binding.cart.Cart;
import ms.bus.xml.binding.movies.MovieCatalog;
import ms.bus.xml.binding.movies.MovieType;
import ms.bus.xml.binding.moviesDetail.DetailList;
import ms.bus.xml.binding.moviesDetail.DetailType;
import ms.dal.dto.Movies;
import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException;

/**
 *
 * @author minh
 */
public class CommonUtil {

    public static void generateJAXB(String ouputPath, String packageName, String schemaFile) {
        try {
            SchemaCompiler sc = XJC.createSchemaCompiler();
            sc.setErrorListener(new ErrorListener() {

                public void error(SAXParseException saxpe) {
                    System.out.println("ERROR " + saxpe.getMessage());
                }

                public void fatalError(SAXParseException saxpe) {
                    System.out.println("ERROR " + saxpe.getMessage());
                }

                public void warning(SAXParseException saxpe) {
                    System.out.println("ERROR " + saxpe.getMessage());
                }

                public void info(SAXParseException saxpe) {
                    System.out.println("ERROR " + saxpe.getMessage());
                }
            });

            sc.forcePackageName(packageName);
            File schema = new File(schemaFile);
            InputSource is = new InputSource(schema.toURI().toString());
            sc.parseSchema(is);
            S2JJAXBModel model = sc.bind();
            JCodeModel code = model.generateCode(null, null);
            code.build(new File(ouputPath));

        } catch (IOException e) {
            System.out.println("IOException on CommonUtil " + e.getMessage());
        } catch (Exception e) {
            System.out.println("Exception on CommonUtil " + e.getMessage());
        }
    }

    public static void marshallMovies(List<Movies> movieList, File file) {
        try {
            MovieCatalog movieCatalog = new MovieCatalog();
            if (movieList != null || !movieList.isEmpty()) {
                for (int i = 0; i < movieList.size(); i++) {
                    MovieType movieType = new MovieType();
                    movieType.setId(movieList.get(i).getMovieId());
                    movieType.setTitle(movieList.get(i).getTitle());
                    movieType.setPoster(movieList.get(i).getPoster());
                    movieType.setImdbRate(movieList.get(i).getImdbRate());
                    // convert java util date to XMLGregorianCalendar
                    GregorianCalendar c = new GregorianCalendar();
                    c.setTime(movieList.get(i).getReleaseDate());
                    XMLGregorianCalendar releaseDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
                    movieType.setReleaseDate(releaseDate);
                    movieType.setPrice(movieList.get(i).getPrice());
                    movieCatalog.getMovie().add(movieType);
                }
            }
            JAXBContext ctx = JAXBContext.newInstance(movieCatalog.getClass());
            Marshaller mar = ctx.createMarshaller();
            mar.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            mar.marshal(movieCatalog, file);
            System.out.println("****** Create XML success *****");
        } catch (JAXBException ex) {
            System.out.println("****** Fail to create XML file *******");
            Logger.getLogger(CommonUtil.class.getName()).log(Level.SEVERE, null, ex);
        } catch (DatatypeConfigurationException ex) {
            Logger.getLogger(CommonUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void marshallMoviesDetail(List<Movies> movieList, File file) {
        try {
            DetailList detailList = new DetailList();
            if (movieList != null || !movieList.isEmpty()) {
                for (int i = 0; i < movieList.size(); i++) {
                    DetailType detailType = new DetailType();
                    detailType.setId(movieList.get(i).getMovieId());
                    detailType.setTitle(movieList.get(i).getTitle());
                    detailType.setPoster(movieList.get(i).getPoster());
                    detailType.setDescription(movieList.get(i).getDescription());
                    detailType.setActors(movieList.get(i).getActors());
                    detailType.setImdbRate(movieList.get(i).getImdbRate());
                    // convert java util date to XMLGregorianCalendar
                    GregorianCalendar c = new GregorianCalendar();
                    c.setTime(movieList.get(i).getReleaseDate());
                    XMLGregorianCalendar releaseDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
                    detailType.setReleaseDate(releaseDate);
                    detailType.setPrice(movieList.get(i).getPrice());
                    detailList.getMovieDetail().add(detailType);
                }
            }
            JAXBContext ctx = JAXBContext.newInstance(detailList.getClass());
            Marshaller mar = ctx.createMarshaller();
            mar.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            mar.marshal(detailList, file);
            System.out.println("****** Create XML success *****");
        } catch (JAXBException ex) {
            System.out.println("****** Fail to create XML file *******");
            Logger.getLogger(CommonUtil.class.getName()).log(Level.SEVERE, null, ex);
        } catch (DatatypeConfigurationException ex) {
            Logger.getLogger(CommonUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    // not yet implement
    public static Cart unMarshallCart(File file) {
        try {
            JAXBContext jc = JAXBContext.newInstance("ms.bus.xml.binding.cart");
            Unmarshaller u = jc.createUnmarshaller();
            return (Cart) u.unmarshal(file);
        } catch (JAXBException ex) {
            Logger.getLogger(CommonUtil.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public static void main(String[] args) {
        //generateJAXB("src/java", "ms.bus.xml.binding.movies", "src/java/ms/bus/xml/schema/movies.xsd");
        //generateJAXB("src/java", "ms.bus.xml.binding.moviesDetail", "src/java/ms/bus/xml/schema/moviesDetail.xsd");
        //generateJAXB("src/java", "ms.bus.xml.binding.cart", "src/java/ms/bus/xml/schema/movieCart.xsd");
//        File xmlInput = new File("src/java/shoppingCart.xml");
//        Cart cart = unMarshallCart(xmlInput);
//        Handler handler = new Handler();
//        handler.insertNewOrder(cart, 1, new Date());
    }
}
